package com.hqd.jjvm.jnative;

import com.hqd.jjvm.rtda.JThread;
import com.hqd.jjvm.rtda.LocalVars;
import com.hqd.jjvm.rtda.heap.JClass;
import com.hqd.jjvm.rtda.heap.JMethod;
import com.hqd.jjvm.rtda.obj.JObject;
import com.hqd.jjvm.util.ClassUtil;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 注册本地方法
 */
public class JNativeRegistry {
    public static final Map<String, JNativeFunction> JNATIVE_METHOD_MAP = new ConcurrentHashMap<>();

    protected static void registerNatives(JThread jThread) {
        /**
         * TODO 啥也不干
         */
    }

    public static void registry(JMethod method, JNativeFunction function) {
        registry(method.getJClass().getClassName(), method.getName(), method.getDescriptor(), function);
    }

    public static void registry(String classPath, String methodName, String descriptor, JNativeFunction function) {
        String name = classPath + "." + methodName + "." + descriptor;
        JNATIVE_METHOD_MAP.put(name, function);
    }

    public static JNativeFunction getJNativeFunction(JMethod method) {
        String name = method.getJClass().getClassName() + "." + method.getName() + "." + method.getDescriptor();
        return JNATIVE_METHOD_MAP.get(name);
    }

    public static void isPrimitive(JThread jThread) {
        JObject jObject = jThread.getJvmStack().getTop().getLocalVars().getRefVal(0);
        JClass jc = (JClass) jObject.getExtra();
        if (ClassUtil.isPrimitive(jc)) {
            jThread.getJvmStack().pushOperandStackIntVal(1);
        } else {
            jThread.getJvmStack().pushOperandStackIntVal(0);
        }
    }

    public static void isAssignableFrom(JThread jThread) {
        LocalVars localVars = jThread.getJvmStack().getTop().getLocalVars();
        JObject jObject = localVars.getRefVal(0);
        JObject cls = localVars.getRefVal(1);
        JClass thisJC = (JClass) jObject.getExtra();
        JClass clsJC = (JClass) cls.getExtra();
        jThread.getJvmStack().pushOperandStackBoolVal(thisJC.isAssignableFrom(clsJC));
    }
}
